#include <gtest/gtest.h>

#include "kiva/node.h"

namespace kiva {

namespace {

TEST(Node, CtorForConstant) {
  {
    Node n;
    EXPECT_EQ(n.type(), NodeType::kNop);
  }
  {
    Node n(1l);
    EXPECT_EQ(n.type(), NodeType::kLong);
    EXPECT_EQ(n.long_value(), 1l);
    EXPECT_TRUE(Node::IsConstant(n.type()));
  }
  {
    Node n(1ul);
    EXPECT_EQ(n.type(), NodeType::kULong);
    EXPECT_EQ(n.ulong_value(), 1ul);
    EXPECT_TRUE(Node::IsConstant(n.type()));
  }
  {
    Node false_node(false);
    Node true_node(true);
    EXPECT_EQ(false_node.type(), NodeType::kBool);
    EXPECT_EQ(true_node.type(), NodeType::kBool);
    EXPECT_TRUE(true_node.bool_value());
    EXPECT_FALSE(false_node.bool_value());
    EXPECT_TRUE(Node::IsConstant(true_node.type()));
    EXPECT_TRUE(Node::IsConstant(false_node.type()));
  }
  {
    Node n(1.0);
    EXPECT_FLOAT_EQ(n.float_value(), 1.0);
    EXPECT_EQ(n.type(), NodeType::kFloat);
    EXPECT_TRUE(Node::IsConstant(n.type()));
  }
  {
    Node n("string");
    EXPECT_EQ(n.type(), NodeType::kString);
    EXPECT_EQ(n.string_value(), "string");
  }
  {
    Node n(std::string_view("string"));
    EXPECT_EQ(n.type(), NodeType::kString);
    EXPECT_EQ(n.string_value(), "string");
  }
  {
    std::string str("string");
    Node n(str);
    EXPECT_EQ(n.type(), NodeType::kString);
    EXPECT_EQ(n.string_value(), "string");
  }
  {
    Node n(std::string("string"));
    EXPECT_EQ(n.type(), NodeType::kString);
    EXPECT_EQ(n.string_value(), "string");
  }
  {
    Node n("id", Node::name_t{});
    EXPECT_EQ(n.type(), NodeType::kName);
    EXPECT_EQ(n.string_value(), "id");
  }
}

TEST(Node, NodeThatHasChildren) {
  {
    Node n(NodeType::kFor);
    EXPECT_EQ(n.type(), NodeType::kFor);
    EXPECT_EQ(n.num_children(), 0);
    EXPECT_TRUE(n.children().empty());

    auto child = new Node(0l);
    n.AddChild(child);
    EXPECT_EQ(n.num_children(), 1);
    EXPECT_EQ(n.child_at(0), child);
    EXPECT_EQ(n.child_at(0)->long_value(), 0);
  }
}

}  // namespace

}  // namespace kiva
